package debby.bdmap.utils

import com.baidu.mapapi.map.PolygonOptions
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.utils.AreaUtil
import com.baidu.mapapi.utils.DistanceUtil


/**
 * Created by debby on 2018/6/15.
 * 描述:计算
 */

/**
 * 距离计算
 */
fun getDistance(p1: LatLng, p2: LatLng): Double {
    return DistanceUtil.getDistance(p1, p2)
}

/**
 * 矩形面积计算
 */
fun calculateArea(northeast: LatLng, southwest: LatLng): Double {
    return AreaUtil.calculateArea(northeast, southwest)
}

/**
 * 计算多边形面积
 * @return
 */
fun getArea(pts: List<LatLng>): String {
    val totalArea: Double// 初始化总面积
    var lowX: Double
    var lowY: Double
    var middleX: Double
    var middleY: Double
    var highX: Double
    var highY: Double
    var AM: Double
    var BM: Double
    var CM: Double
    var AL: Double
    var BL: Double
    var CL: Double
    var AH: Double
    var BH: Double
    var CH: Double
    var CoefficientL: Double
    var CoefficientH: Double
    var aLtangent: Double
    var BLtangent: Double
    var CLtangent: Double
    var AHtangent: Double
    var BHtangent: Double
    var CHtangent: Double
    var ANormalLine: Double
    var BNormalLine: Double
    var CNormalLine: Double
    var OrientationValue: Double
    var AngleCos: Double
    var Sum1 = 0.0
    var Sum2 = 0.0
    var Count2 = 0.0
    var Count1 = 0.0
    val Sum: Double
    val Radius = 6378137.0// WGS84椭球半径
    val Count = pts.size
    //最少3个点
    if (Count < 3) {
        return ""
    }
    for (i in 0 until Count) {
        when (i) {
            0 -> {
                lowX = pts[Count - 1].longitude * Math.PI / 180
                lowY = pts[Count - 1].latitude * Math.PI / 180
                middleX = pts[0].longitude * Math.PI / 180
                middleY = pts[0].latitude * Math.PI / 180
                highX = pts[1].longitude * Math.PI / 180
                highY = pts[1].latitude * Math.PI / 180
            }
            Count - 1 -> {
                lowX = pts[Count - 2].longitude * Math.PI / 180
                lowY = pts[Count - 2].latitude * Math.PI / 180
                middleX = pts[Count - 1].longitude * Math.PI / 180
                middleY = pts[Count - 1].latitude * Math.PI / 180
                highX = pts[0].longitude * Math.PI / 180
                highY = pts[0].latitude * Math.PI / 180
            }
            else -> {
                lowX = pts[i - 1].longitude * Math.PI / 180
                lowY = pts[i - 1].latitude * Math.PI / 180
                middleX = pts[i].longitude * Math.PI / 180
                middleY = pts[i].latitude * Math.PI / 180
                highX = pts[i + 1].longitude * Math.PI / 180
                highY = pts[i + 1].latitude * Math.PI / 180
            }
        }
        AM = Math.cos(middleY) * Math.cos(middleX)
        BM = Math.cos(middleY) * Math.sin(middleX)
        CM = Math.sin(middleY)
        AL = Math.cos(lowY) * Math.cos(lowX)
        BL = Math.cos(lowY) * Math.sin(lowX)
        CL = Math.sin(lowY)
        AH = Math.cos(highY) * Math.cos(highX)
        BH = Math.cos(highY) * Math.sin(highX)
        CH = Math.sin(highY)
        CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL)
        CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH)
        aLtangent = CoefficientL * AL - AM
        BLtangent = CoefficientL * BL - BM
        CLtangent = CoefficientL * CL - CM
        AHtangent = CoefficientH * AH - AM
        BHtangent = CoefficientH * BH - BM
        CHtangent = CoefficientH * CH - CM
        AngleCos = (AHtangent * aLtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent

                + CHtangent * CHtangent) * Math.sqrt(aLtangent * aLtangent + BLtangent * BLtangent + CLtangent * CLtangent))
        AngleCos = Math.acos(AngleCos)
        ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent
        BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * aLtangent)
        CNormalLine = AHtangent * BLtangent - BHtangent * aLtangent
        OrientationValue = when {
            AM != 0.0 -> ANormalLine / AM
            BM != 0.0 -> BNormalLine / BM
            else -> CNormalLine / CM
        }
        if (OrientationValue > 0) {
            Sum1 += AngleCos
            Count1++
        } else {
            Sum2 += AngleCos
            Count2++
        }
    }

    val tempSum1: Double
    val tempSum2: Double
    tempSum1 = Sum1 + (2.0 * Math.PI * Count2 - Sum2)
    tempSum2 = 2.0 * Math.PI * Count1 - Sum1 + Sum2
    Sum = if (Sum1 > Sum2) {
        if (tempSum1 - (Count - 2) * Math.PI < 1)
            tempSum1
        else
            tempSum2
    } else {
        if (tempSum2 - (Count - 2) * Math.PI < 1)
            tempSum2
        else
            tempSum1
    }
    totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius
    return Math.floor(totalArea).toString() // 返回总面积
}